package cn.fsw.pethome.base.service.impl;

import cn.fsw.pethome.base.domain.dto.VerifyDTO;
import cn.fsw.pethome.base.service.IVerifyCodeService;
import cn.fsw.pethome.constants.BaseConstants;
import cn.fsw.pethome.user.domain.User;
import cn.fsw.pethome.user.mapper.UserMapper;
import cn.fsw.pethome.util.BusinessException;
import cn.fsw.pethome.util.StrUtils;
import cn.fsw.pethome.util.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String VerifyCode(String key) {
        try {
            if(StringUtils.isEmpty(key)){
                throw new BusinessException("网络异常");
            }
            String code = StrUtils.getComplexRandomString(4);
            String verifyCode = VerifyCodeUtils.VerifyCode(110, 40, code);
            redisTemplate.opsForValue().set(BaseConstants.register.REGISTER +key,code,5, TimeUnit.MINUTES);
            return verifyCode;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
    /*获取手机验证码执行流程*/
    @Override
    public void sendMobileCode(VerifyDTO verifyDTO){
        //1.验证手机号是否为null
        if(StringUtils.isEmpty(verifyDTO.getPhone())){
            throw new BusinessException("手机号不能为空");
        }
        if(verifyDTO.getType() == 0){
            imgCode(verifyDTO);
        }else {
            sendCode(verifyDTO);
        }

    }
    //注册图片验证码
    private void imgCode(VerifyDTO verifyDTO){
        //2.验证图片码是否为null
        if(StringUtils.isEmpty(verifyDTO.getImageCode())){
            throw new BusinessException("图片验证码不能为空");
        }
        //3.图片验证码的key是否为null
        if(StringUtils.isEmpty(verifyDTO.getImageCodeKey())){
            throw new BusinessException("非法访问");
        }
        //4.去校验图片验证码和redis中的图片验证码是否一致
        Object VerifyCode = redisTemplate.opsForValue().get(BaseConstants.register.REGISTER + verifyDTO.getImageCodeKey());
        if(VerifyCode == null){
            throw new BusinessException("图片验证码已过期");
        }
        if(!VerifyCode.toString().equalsIgnoreCase(verifyDTO.getImageCode())){
            throw new BusinessException("图片验证码错误");
        }
        //5.去数据库里面校验 手机号是否存在
        User user = userMapper.selectByPhoneUser(verifyDTO.getPhone());
        sendCode(BaseConstants.register.REGISTER+verifyDTO.getPhone(),user);

    }

    //绑定 发送短信验证
    private void sendCode(VerifyDTO verifyDTO){
       User user =  userMapper.selectByPhoneUserAndWXUser(verifyDTO.getPhone());
        sendCode(BaseConstants.register.BINDER+verifyDTO.getPhone(),user);
    }

    private void sendCode(String key,User user){
        //5.1 抛出业务异常 手机号已存在 请去登录
        if(user != null){
            throw new BusinessException("该手机号已存在");
        }
        //6.1.2 生成一个key 手机号+业务键
        //6.去redis中去查询是否存在验证码
        Object smCode = redisTemplate.opsForValue().get(key);
        //6.1.1 生成一个验证码
        String randomCode = StrUtils.getRandomString(4);
        //6.1不存在验证码
        if (smCode == null){
            //6.1.3 生成一个value  code+时间戳   （时间戳做重复发送短信的校验）
            long currentTimeMillis = System.currentTimeMillis();//当前时间戳
            String value = randomCode+":"+currentTimeMillis;
            //设置有效时间
            redisTemplate.opsForValue().set(key,value,3,TimeUnit.MINUTES);
        }else {
            //6.2存在验证码
            //6.2.1 判断当前整个key是否超过1分钟
            String[] split = smCode.toString().split(":");
            /*上一次的时间*/
            String LastTime = split[1];
            if((System.currentTimeMillis() - Long.parseLong(LastTime)) < 1000*60){
                //6.2.1.2  不超过 抛出异常
                throw new BusinessException("请勿重复获取验证码");
            }else {
                //6.2.1.1  超过 重写生成发送短信验证码 更新时间戳(把之前的取出来)   有效时间3分钟
                redisTemplate.opsForValue().set(key,split[0]+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
                randomCode = split[0];
            }

        }
        //发送短信
        /* SendMsgUtil.SendMsg(key,verifyDTO.getPhone(),randomCode);*/
        System.out.println(randomCode);
    }
}
